﻿using OAuth2Authorizer.Framework;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;

namespace OAuth2Authorizer
{
    public class AuthorizerBuilder
    {
        public static IAuthorizer Create(BuiltInAuthorizers builtIn)
        {
            string typeName = string.Format("OAuth2Authorizer.{0}.{1}Authorizer", builtIn.ToString(), builtIn.ToString());
            var type = Type.GetType(typeName);
            return (IAuthorizer)Activator.CreateInstance(type);
        }

        public static IAuthorizer CreateDefault(string authorizeUrl, string tokenUrl)
        {
            var defaultAuthorizer = new DefaultAuthorizer();
            defaultAuthorizer.AuthorizeUrl = authorizeUrl;
            defaultAuthorizer.TokenUrl = tokenUrl;
            return defaultAuthorizer;
        }

        private GenericAuthorizer _authorizer = new GenericAuthorizer();
        private ResponseTypeBuilder _builder = new ResponseTypeBuilder();

        public AuthorizerBuilder() {}

        public void BuildAuthorizeUrlTemplate(string authorizeUrl, string appKeyString="client_id", string redirectUrlString="redirect_uri", string stateString="state")
        {
            _authorizer.AuthorizeUrl = authorizeUrl;
            string template = "{0}?" + appKeyString + "={1}&" + redirectUrlString + "={2}";
            if (!string.IsNullOrEmpty(stateString))
            {
                template += "&" + stateString + "={3}";
                _authorizer.UseState = true;
            }
            _authorizer.AuthorizeUrlTemplate = template;
        }

        public void BuildTokenRequest(string tokenUrl, string appKeyString = "client_id", string appSecretString = "client_secret", string redirectUrlString = "redirect_uri", string codeString = "code")
        {
            _authorizer.TokenUrl = tokenUrl;
            _authorizer.TokenRequestTemplate = appKeyString + "={0}&" + appSecretString + "={1}&" + redirectUrlString + "={2}&" + codeString + "={3}";
        }

        public void BuildResponseType(string accessTokenName, string tokenTypeName, params string[] properties)
        {
            _builder.BuildType("GenericAccessTokenResponse");
            _builder.BuildProperty("AccessToken", string.IsNullOrEmpty(accessTokenName) ? "access_token" : accessTokenName);
            _builder.BuildProperty("TokenType", string.IsNullOrEmpty(tokenTypeName) ? "token_type" : tokenTypeName);
            foreach (var property in properties)
                _builder.BuildProperty(property, property);
            _builder.BuildConverterMethod();
            _authorizer.ResponseType = _builder.ResponseType;
        }

        public IAuthorizer Authorizer
        {
            get { return _authorizer; }
        }
    }
}
